#include <iostream>
#include <boost/filesystem/path.hpp>
#include <string>
#include <fstream>
#include <stdio.h>
#include <math.h>
#include <algorithm>
#include "CmdLine/cmdargs.h"
#include "get_arg.h"
using std::string;
using std::ofstream;
using std::ifstream;
using std::fstream;
using std::cerr;
using std::cout;




//_______________________________________________________________________________________

//		process_command_line_options

//				from command line
//				Created [9/13/2001]

//_______________________________________________________________________________________
bool process_command_line_options(int argc, char* argv[], t_program_args& args)
{
	// optional help directive
	CmdArgUsage opt_help('h', "help", 	"display this message", &cerr);

	// required options
	// const unsigned REQUIRED = CmdArg::isREQ | CmdArg::isVALREQ;
	CmdArgStr opt_output_prefix	('p', "prefix", "<string>",
								"Output files will have the supplied strings as a prefix. "
								"This can include the relative or absolute file path.");
	CmdArgStr opt_taxon1		('a', "a_species", "<string>",
								"string to identify species A sequences. "
								"Defaults to ENSMUS.");
	CmdArgStr opt_taxon2		('b', "b_species", "<string>",
								"string to identify species B sequences."
								"Defaults to ENSRNO.");
	CmdArgSet opt_fill_lacunae	('n', "nulls",
								"Replace null or out of range values (lacunae) values");
	CmdArgSet opt_scale_data	('s', "scale_orthologs",
								"Scale orthologs with a different evolutionary clock.");
	CmdArgFloat opt_speciation	('S', "Specification_time", "<double>",
								"The specification time point (from the present) "
								"in Ks units.");
	CmdArgInt opt_keyhole_size	('k', "keyhole_optimization_size", "number",
								"When using Kitsch to optimise UPGMA trees, the maximum "
								"subbranch size to optimize at one go.");
	CmdArgInt opt_cnt_random_global_searches
								('r', "random_global_searches", "number",
								"When using Kitsch, how many times the data should be "
								"randomly reordered to search for a different "
								"global optimum.");
	CmdArgFloat opt_clock_adjust('C', "Clock_adjustment", "<double>",
								"The evolutionary clock of species B relative to A since "
								"specification.");
	CmdArgFloat opt_power		('w', "weighting_falloff", "<double>",
								"for weights in Kitch = nth power of the denominator. "
								"If > 2, the weighting of errors will fall off sharply "
								"for greater distances.");
	CmdArgSet opt_upgma			('U', "UPGMA",
								"(Default)Use UPGMA rather than Fitsch with contempraneous tips.");
	CmdArgSet opt_kitsch		('K', "KITSCH",
								"Use Fitsch with contempraneous tips rather than UPGMA.");
	CmdArgSet opt_optimize_kitsch('O', "Optimize_using_kitsch",
								"Use Fitsch with contempraneous tips on top of UPGMA.");
	CmdArgStr opt_ks_file		("[ks_distance_file]",
								"Tab delimited file with Ks distances.");
	
	opt_fill_lacunae = false;
	opt_scale_data = false;
	opt_speciation = 0.2;
	opt_clock_adjust = 1.0;
	opt_upgma = true;
	opt_kitsch = false;
	opt_optimize_kitsch = false;
	opt_keyhole_size	= 5;
	opt_power			= -1.0;
	
	
	
	string exe_file_name =  boost::filesystem::path(*argv).leaf();
	
	// construct command line
	CmdLine  cmdline(exe_file_name.c_str(),
							&opt_output_prefix,
							&opt_taxon1,
							&opt_taxon2,
							&opt_fill_lacunae,
							&opt_scale_data,
							&opt_speciation,
							&opt_clock_adjust,
							&opt_upgma,
							&opt_kitsch,
							&opt_ks_file,
							&opt_keyhole_size,
							&opt_optimize_kitsch,
							&opt_cnt_random_global_searches,
							&opt_power,
							0);
	cmdline.description(
		"This programme takes Ks distances from either STDIN or the command line "
		"and resolves the phylogenetic tree of one or more group of paralogs.\n\n"
		
		"Ks distances are supplied in tab delimited file in three column format: "
			"gene1 gene2 Ks_distance.");

	// parse command line
	CmdArgvIter  argv_iter(--argc, ++argv);
	// report command line errors
	if (cmdline.parse(argv_iter))
		return false;

	args.taxon1				= opt_taxon1;
	args.taxon2				= opt_taxon2;
	if (!args.taxon1.length())
		 args.taxon1 = "ENSMUS";
	if (!args.taxon2.length())
		 args.taxon2 = "ENSRNO";
	args.fill_lacunae		= opt_fill_lacunae;
	args.scale_data			= opt_scale_data;
	args.speciation			= opt_speciation;
	args.clock_adjust		= opt_clock_adjust;
	
	if (opt_optimize_kitsch)
	{
		args.analysis_type	= eUPGMA_KITSCH;
	}
	else
	if (opt_kitsch)
	{
		args.analysis_type	= eKITSCH;	
	}
	else
	{
		args.analysis_type	= eUPGMA;
	}
	args.ks_file			= opt_ks_file;
	args.out_file_prefix	= opt_output_prefix;
	args.cnt_random_global_searches	= opt_cnt_random_global_searches;
	args.cnt_random_global_searches = (opt_cnt_random_global_searches > 0) ?
								opt_cnt_random_global_searches : 10;
	args.cnt_random_global_searches = std::min(args.cnt_random_global_searches, 5000U);
	args.keyhole_size		= (opt_keyhole_size > 5) ? opt_keyhole_size : 5;
	args.keyhole_size		= std::min (args.keyhole_size, 5000U);
	args.power				= opt_power;
	if (args.power< 0.0)
		args.power= 2.0;
	return true;
}






